/*
 * carl9170 firmware - used by the ar9170 wireless device
 *
 * Interface to the WLAN part of the chip
 *
 * Copyright (c) 2000-2005 ZyDAS Technology Corporation
 * Copyright (c) 2007-2009 Atheros Communications, Inc.
 * Copyright	2009	Johannes Berg <johannes@sipsolutions.net>
 * Copyright 2009-2012	Christian Lamparter <chunkeey@googlemail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

void handle_wlan(void)
{
	uint32_t intr;

	intr = get(AR9170_MAC_REG_INT_CTRL);
	/* ACK Interrupt */
	set(AR9170_MAC_REG_INT_CTRL, intr);

#define HANDLER(intr, flag, func)			\
	do {						\
		if ((intr & flag) != 0) {		\
			func();				\
		}					\
	} while (0)

	intr |= fw.wlan.soft_int;
	fw.wlan.soft_int = 0;

	HANDLER(intr, AR9170_MAC_INT_PRETBTT, handle_pretbtt);

	HANDLER(intr, AR9170_MAC_INT_ATIM, handle_atim);

	HANDLER(intr, AR9170_MAC_INT_RXC, handle_wlan_rx);

	HANDLER(intr, (AR9170_MAC_INT_TXC | AR9170_MAC_INT_RETRY_FAIL),
		handle_wlan_tx_completion);

#ifdef CONFIG_CARL9170FW_DEBUG
	HANDLER(intr, AR9170_MAC_INT_QOS, handle_qos);

	HANDLER(intr, AR9170_MAC_INT_RADAR, handle_radar);
#endif /* CONFIG_CARL9170FW_DEBUG */

	HANDLER(intr, AR9170_MAC_INT_CFG_BCN, handle_beacon_config);

	if (unlikely(intr))
		DBG("Unhandled Interrupt %x\n", (unsigned int) intr);

	wlan_janitor();

#undef HANDLER
}

void __cold wlan_timer(void)
{
	unsigned int cached_mac_reset;

	cached_mac_reset = fw.wlan.mac_reset;

	/* TX Queue Hang check */
	wlan_check_hang();

	/* RX Overrun check */
	wlan_check_rx_overrun();

	if (unlikely(fw.wlan.mac_reset >= CARL9170_MAC_RESET_RESET)) {
		wlan_mac_reset();
		fw.wlan.mac_reset = CARL9170_MAC_RESET_OFF;
	} else {
		if (fw.wlan.mac_reset && cached_mac_reset == fw.wlan.mac_reset)
			fw.wlan.mac_reset--;
	}
}

